package com.ahui.util;

import com.ahui.constant.FileExtensionConstant;
import com.ahui.constant.SupportedFileTypeConst;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : ph.li
 * @date : 2023/7/29 16:57
 */
@Slf4j
public class PdfUtil {

    /**
     * pdf转换为图片路径列表
     * @param file pdf文件
     * @param outputPath 图片输出路径
     * @return
     */
    public static List<String> pdf2img(File file, String outputPath) {
        if (!FileUtil.isPdfFile(file)) {
            log.error("文件：{}不是pdf文件", file.getAbsolutePath());
            return null;
        }

        PDDocument doc = null;
        List<String> imgPathList = new ArrayList<>();
        try {
            // 写入文件
            doc = PDDocument.load(file);
            PDFRenderer renderer = new PDFRenderer(doc);
            int pageCount = doc.getNumberOfPages();
            BufferedImage image = null;
            for (int i = 0; i < pageCount; i++) {
                // dpi为144，越高越清晰，转换越慢
                image = renderer.renderImageWithDPI(i, 144); // Windows native DPI
                // 将图片写出到该路径下
                String imgPath = outputPath + File.separator + FileUtil.getFileNameNoExtName(file.getName()) + "_" + (i + 1) + FileExtensionConstant.JPG;
                ImageIO.write(image, SupportedFileTypeConst.JPG, new File(imgPath));
                imgPathList.add(imgPath);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                assert doc != null;
                doc.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return imgPathList;
    }

    /**
     * 将图片列表转换为pdf文件
     * @param imgPaths 文件路径列表
     * @param outputPath pdf文件输出路径
     * @param fileName pdf文件名
     * @throws IOException
     */
    public static void imgList2Pdf(List<String> imgPaths,String outputPath,String fileName) throws IOException {

        PDDocument doc = new PDDocument();
        for (String imageFile : imgPaths) {
            PDPage page = new PDPage();
            doc.addPage(page);

            PDImageXObject image = PDImageXObject.createFromFile(imageFile, doc);
            PDPageContentStream contentStream = new PDPageContentStream(doc, page);
            contentStream.drawImage(image, 0, 0, page.getMediaBox().getWidth(), page.getMediaBox().getHeight());
            contentStream.close();
        }
        String filePath = outputPath + File.separator + fileName + FileExtensionConstant.PDF;
        doc.save(filePath); // 保存为一个PDF文件
        doc.close();
    }

    /**
     * 多个pdf合并为一个pdf
     * @throws FileNotFoundException
     */
    public static void mergerPDF(List<File> files,String outputPath,String fileName) throws FileNotFoundException {
        String outputFilePath = outputPath + File.separator + fileName + FileExtensionConstant.PDF;
        List<InputStream> inputStreams = files.stream().map(file -> {
            try {
                return new FileInputStream(file);
            } catch (FileNotFoundException e) {
                throw new RuntimeException(e);
            }
        }).collect(Collectors.toList());
        PDFMergerUtility merger = new PDFMergerUtility();
        merger.setDestinationFileName(outputFilePath);
        merger.addSources(inputStreams);
        // 添加要合并的 PDF 文件
        /*merger.addSource(new File("file1.pdf"));
        merger.addSource(new File("file2.pdf"));
        merger.addSource(new File("file3.pdf"));*/

        try {
            // 合并 PDF 文件
            merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
            System.out.println("合并完成！");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
